void setup() {
  size(1000, 1000); 
  background(0);
  noLoop();
}
void dottedLine(float x0,float y0,float x1,float y1){
  float segx=(x1-x0)/11;
  float segy=(y1-y0)/11;
  for(int i=0;i<11;i++){
    if(i%2==0){
      line(x0+i*segx,y0+segy*i,x0+segx*i+segx,y0+segy*i+segy);
    }
  }
}
void line3d(Point3D sp,Point3D ep,boolean dotted){
  float tx0=sp.y*sqrt(2)/2+sp.x;
  float ty0=sp.y*sqrt(2)/2+sp.z;
  float tx1=ep.y*sqrt(2)/2+ep.x;
  float ty1=ep.y*sqrt(2)/2+ep.z;
  tx0=width/2+tx0;
  tx1=width/2+tx1;
  ty0=height/2-ty0;
  ty1=height/2-ty1;
  if(dotted){
    dottedLine(tx0,ty0,tx1,ty1);
  }else{
    line(tx0,ty0,tx1,ty1);
  }
}
void draw() {
  ellipse(width/2,height/2,50,50);
  stroke(255,0,255);
  Point3D pa=new Point3D(0,0,0);
  Point3D pb=pa.move(100,0,0);
  Point3D pc=pa.move(100,100,0);
  Point3D pd=pa.move(0,100,0);
  line3d(pa,pb,false);
  line3d(pb,pc,false);
  line3d(pc,pd,true);
  line3d(pd,pa,true);
  Point3D pa1=pa.move(0,0,100);
  Point3D pb1=pb.move(0,0,100);
  Point3D pc1=pc.move(0,0,100);
  Point3D pd1=pd.move(0,0,100);
  line3d(pa1,pb1,false);
  line3d(pc1,pb1,false);
  line3d(pc1,pd1,false);
  line3d(pa1,pd1,false);
  
  line3d(pa1,pa,false);
  line3d(pb,pb1,false);
  line3d(pc,pc1,false);
  line3d(pd,pd1,true);
  
  Point3D ppa=new Point3D(200,0,0);
  Point3D ppb=ppa.move(50,85,0);
  Point3D ppc=ppa.move(-50,85,0);
  Point3D ppd=ppa.move(0,56,50);
  line3d(ppa,ppb,false);
  line3d(ppb,ppc,true);
  line3d(ppa,ppc,false);
  line3d(ppd,ppa,false);
  line3d(ppd,ppb,false);
  line3d(ppd,ppc,false);
  Point3D ppe=ppa.move(0,56,0);
  line3d(ppd,ppe,true);
  Point3D ppf=ppa.move(0,85,0);
  line3d(ppa,ppf,true);
}
class Point3D{
  float x=0;
  float y=0;
  float z=0;
  Point3D(float x,float y,float z){
    this.x=x;
    this.y=y;
    this.z=z;
  }
  Point3D move(float mx,float my,float mz){
    return new Point3D(x+mx,y+my,z+mz);
  }
}
